<?php
/**
 * Created by PhpStorm.
 * User: zhengze
 * Date: 2019/7/1
 * Time: 18:29
 */

namespace app\admin\logic;

use app\common\event\AdminLogin;
use app\common\exception\ExceptionEmun;
use app\common\exception\UserException;
use app\common\logic\BaseLogic;
use app\common\model\Admin;
use app\common\model\AdminGroupRelation;
use app\common\token\Token;
use app\common\traits\InstanceTrait;
use app\common\validate\AdminValidate;
use Helper\ArrayHelper;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\facade\Db;
use think\model\Collection;

/**
 * Class AdminLogic
 * @package app\admin\logic
 */
class AdminLogic extends BaseLogic
{
    use InstanceTrait;

    public function __construct($model = NULL)
    {
        $model = $model ?? Admin::instance();
        parent::__construct($model);
    }

    /**
     * 登录
     * @return \app\common\model\base\BaseModel|false|null
     * @throws \app\common\exception\BaseException
     */
    public function login()
    {
        $Admin = Admin::instance();
        $userInfo = AdminValidate::instance()
                                 ->getTempAdmin();
        if ($userInfo['status'] === 0) {
            ExceptionEmun::throwException(UserException::LOCKED);
            return FALSE;
        }
        // 获取菜单和权限
        $admin_id = $userInfo[$Admin->getPk()];
        event(AdminLogin::class, $admin_id);
        return $userInfo;
    }

    /**
     * 获取菜单和权限
     * @param $admin_info
     * @return null | Array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMenuList($admin_info)
    {
        $menusList = [];
        if (!empty($admin_info)) {
            $admin_info->groups->load('menus');
            $menusList = ArrayHelper::arrayColumnMerge($admin_info['groups'], 'menus');
            $menusList = array_unique($menusList);
            $menusList = Collection::make($menusList)
                                   ->toArray();
            //处理菜单成树状
            $menusList = ArrayHelper::arrayToTree($menusList, 'menu_id', 'pid', 'child', 0, TRUE, array('pid'));
        }
        return $menusList;
    }

    /**
     * 根据uid返回用户信息(权限，菜单，用户信息),
     * 用于获取正在登录用户和已经登录用户的信息
     * @param $uid
     * @return bool
     * @throws app\common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getMore($uid)
    {
        $Admin = Admin::instance();
        $userInfo = $Admin->getById($uid);
        $dataList = $Admin->getMenuList($userInfo);
        if (empty($dataList['menusList'])) {
            ExceptionEmun::throwException(UserException::NO_RIGHT);
            return FALSE;
        }
        $data['userInfo'] = $userInfo;
        $data['menusList'] = $dataList['menusList'];
        return $data;
    }

    /**
     * JWT生成token
     * @param $userinfo ,可以传admin_id
     * @return array
     */
    public function createJwt($userinfo)
    {
        if (!empty($userinfo) && is_int($userinfo)) {
            $userinfo = Admin::instance()->getByID($userinfo);
        }
        $userinfo['model'] = Admin::class;
        $Token = Token::instance();
        $token = $Token->generateToken($userinfo);
        return $token;
    }


    public function getAdminCount($param)
    {
        $Admin = Admin::instance();
        $count = $Admin->getAdminCount($param);
        return $count;
    }

    /**
     * 获取列表
     * @param $param
     * @return \think\Collection
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getAdminList($param)
    {
        $Admin = Admin::instance();
        $list = $Admin->getAdminList($param);
        if (!empty($list) && FALSE == $list->isEmpty()) {
            $list->load(['structure','post']);
        }
        return $list;
    }

    /**
     * 读取详情
     * @param $admin_id
     * @return \app\common\model\base\BaseModel|null
     * @throws \app\common\exception\BaseException
     */
    public function read($admin_id)
    {
        $Admin = Admin::instance();
        $admin = $Admin->getByID($admin_id);
        if (!empty($admin) && FALSE == $admin->isEmpty()) {
            $admin->post;
            $admin->structure;
            $admin->groups;
        }else{
            ExceptionEmun::throwException(UserException::NO_EXIST);
        }
        return $admin;
    }

    /**
     * AdminGroupRelation中间表写入
     * @param $group_id
     * @param $admin_id
     * @param $menus
     */
    protected function insertGroupRelation($admin_id, $groups)
    {

        $groups = ArrayHelper::ToTree($groups);
        $data = AdminGroupRelation::beforeInsertData(['admin_id' => $admin_id]);
        $insertAllDate = [];
        foreach ($groups as $key => $value) {
            $insertAllDate[$key] = $data;
            $insertAllDate[$key]['group_id'] = $value;
        }
        Db::table(AdminGroupRelation::instance()
                                    ->getTable())
          ->insertAll($insertAllDate);
    }

    /**
     * 创建用户
     * @param array $param [description]
     */
    public function createData($param)
    {
        // 验证
        Admin::instance()
             ->startTrans();
        $param['phone'] = 0;
        $param['password'] = encrypt_password($param['password']);
        $Admin = Admin::create($param);
//        太慢,废除
//        $Admin->groups()->saveAll($param['groups']);
        $this->insertGroupRelation($Admin['admin_id'], $param['groups']);
        Admin::instance()
             ->commit();
        return TRUE;
    }


    /**
     * 通过id修改用户
     * @param array $param [description]
     */
    public function updateByID($param)
    {
        $Admin = Admin::instance();
        $id = $param[$Admin->getPk()] ?? $param['id'];
        $Admin->startTrans();
        // 只有超级管理员能操作超级管理员
        if (1 === (int)$id && 1 !== (int)Token::instance()
                                              ->getUserInfo()[$Admin->getPk()]) {
            ExceptionEmun::throwException(UserException::UPDATE_ADMIN);
        }
        $admin = Admin::field($Admin->baseField)
                      ->where('admin_id', '=', $id)
                      ->find();
        if (!$admin) {
            ExceptionEmun::throwException(UserException::NO_EXIST);
        }
        $admin->groups()
              ->detach();
//        太慢,废除
//        $admin->groups()->saveAll($param['groups']);
        $this->insertGroupRelation($id, $param['groups']);
        //填了密码就加密改密码,不填就不改密码
        if (!empty($param['password'])) {
            $param['password'] = encrypt_password($param['password']);
        } else {
            unset($param['password']);
        }
        $admin->save($param);
        $Admin->commit();
        return TRUE;

    }
}
